/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import { isHapModule, Logger, PluginFileUtil, PluginStore } from '../../framework';
import { FilePathConstants, RouterMapConstants } from '../constants';
import { HMRouterExtensionContext } from '../HMRouterExtensionContext';

export class ResourceProcessProcessor {
  private context: HMRouterExtensionContext;

  constructor(context: HMRouterExtensionContext) {
    this.context = context;
  }

  execute(): void {
    Logger.debug(this.context.node.getNodeName(), `Start to copy router map to raw file...`);
    // 1. Copy the router map to the rawFile directory
    this.copyRouterMapToRawFile();
    // 2. Process the HSP module name
    this.processHspModuleName();
  }

  /**
   * Copy the router map to the rawFile directory
   */
  private copyRouterMapToRawFile(): void {
    let routerMapFilePath = PluginFileUtil.pathResolve(
      this.context.currentTarget?.getBuildTargetOutputPath()!,
      FilePathConstants.TEMP_ROUTER_MAP_PATH,
      this.context.currentTarget?.getTargetName()!,
      RouterMapConstants.ROUTER_MAP_NAME
    );
    let rawFilePath = this.context.config.getRawFilePath();
    PluginFileUtil.ensureFileSync(rawFilePath);
    PluginFileUtil.copyFileSync(routerMapFilePath, rawFilePath);
    Logger.info(this.context.node.getNodeName(), `Copy router map to raw file successfully, filePath: ${rawFilePath}`);
  }

  /**
   * Process the HSP module name
   */
  private processHspModuleName(): void {
    if (!isHapModule(this.context.node)) {
      return;
    }
    let rawFilePath = this.context.config.getRawFilePath();
    let rawFileRouterMap = JSON.parse(PluginFileUtil.readFileSync(rawFilePath).toString());
    rawFileRouterMap.hspModuleNames = [...new Set(PluginStore.getInstance().get<string[]>('hspModuleNames')!)];
    rawFileRouterMap.hspModuleNames.push(...this.getRemoteHspModuleNames(this.context.node.getAllPluginIds()!));
    PluginFileUtil.writeFileSync(rawFilePath, JSON.stringify(rawFileRouterMap));
  }

  /**
   * @description get remote hsp module names
   * @param pluginIds Plugin ID array
   * @return string[] HSP module name array
   */
  private getRemoteHspModuleNames(pluginIds: string[]): string[] {
    let remoteHspModuleNames: string[] = [];
    try {
      pluginIds.forEach((id: string) => {
        let context = this.context.node.getContext(id);
        let signedHspObj = context.getOhpmRemoteHspDependencyInfo(true);
        let remoteHspObj = context.getOhpmRemoteHspDependencyInfo(false);
        for (const key in signedHspObj) {
          remoteHspModuleNames.push(signedHspObj[key].name);
        }
        for (const key in remoteHspObj) {
          remoteHspModuleNames.push(remoteHspObj[key].name);
        }
      });
    } catch (error) {
      Logger.warn(
        this.context.node.getNodeName(),
        'Your DevEco Studio version less than 5.0.3.800, may cause remote hsp dependencies get failed'
      );
    }
    return remoteHspModuleNames;
  }
}
